use axum::{extract::Path, routing::get, Json, Router};
use sea_orm::{ query::*, DbBackend, FromQueryResult };
use serde::{ Deserialize, Serialize };

use crate::{code, sea_orm::connect};

#[derive(Debug, Deserialize, Serialize, FromQueryResult)]
pub struct Data {
    id: u32,
	label: String,
    value: String
}

#[derive(Debug, Deserialize, Serialize, FromQueryResult)]
pub struct ChildData {
    id: u32,
    parent: u32,
	label: String,
    value: String,
}

pub async fn list(table: &str) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let conn = connect().await?;
    let stmt = Statement::from_string(
        DbBackend::MySql, 
        format!("select id, label, value, false as isLeaf, 1 as level from {} order by value asc", table)
    );
    let result = Data::find_by_statement(stmt).into_json().all(&conn).await;
    code::send_arr(result)
}

pub async fn child(table: &str, id:i32, level:i32) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let conn = connect().await?;
    let mut query = format!("select * from {} where parent={}", table, id);
    if level>0 {
        query = format!("select id, parent, label, value, false as isLeaf, {} as level from {} where parent={}", level,table, id);
    }else if level == 0 {
        query = format!("select id, parent, label, value, true as isLeaf from {} where parent={}", table, id);
    }
    let stmt = Statement::from_string(
        DbBackend::MySql, 
        query
    );
    let result = ChildData::find_by_statement(stmt).into_json().all(&conn).await;
    code::send_arr(result)
}
// 地区
pub fn area_route() -> Router{
    Router::new()
    .route("/area/province",  get(|| async { list("province").await } ) )
    .route("/area/city/{id}",  get(|Path( id ): Path<String>| async { 
        let x = id;
        if let Ok(f) = x.parse::<i32>(){
            child("city", f, 2).await
        }else{
            code::err("id 必须是数字")
        }
     }) )
    .route("/area/country/{id}",  get(|Path( id ): Path<String>| async { 
        let x = id;
        if let Ok(f) = x.parse::<i32>(){
            child("country", f, 3).await
        }else{
            code::err("id 必须是数字")
        }
    }) )
    .route("/area/street/{id}",  get(|Path( id ): Path<String>| async { 
        let x = id;
        if let Ok(f) = x.parse::<i32>(){
            child("street", f, 0).await
        }else{
            code::err("id 必须是数字")
        }
    }) )
}